package main

import (
	"fmt"
	"strconv"
)

type User struct {
	id   int
	name string
}

// 再Manager中插入匿名字段User，从而Manager就继承了User的方法
type Manager struct {
	User
}

func (self *User) ToString() string { // receiver = &(Manager.User)
	return fmt.Sprintf("User: %p, %v", self, self)
}

func (u *User) getInfo() string {
	return u.name + "__" + strconv.Itoa(u.id)
}

// 方法覆写，manager覆盖掉user的getInfo方法
func (m *Manager) getInfo() string {
	return "MMMM::::" + m.name + "__" + strconv.Itoa(m.id) + "::::MMMM"
}

/*
如果结构体T中包含了结构体S即
type T struct {
	S
}
那么T就继承了S的所有方法

*/
func main() {
	m := Manager{User{1, "Tom"}}
	fmt.Printf("Manager: %p\n", &m)
	fmt.Println(m.ToString()) // 这个ToString是User的方法，但是Manager也可以调用

	fmt.Println(m.User, m.User.name, m.id) // {1 Tom} Tom 1

	// 调用m自己的getInfo方法
	fmt.Println(m.getInfo()) //	MMMM::::Tom__1::::MMMM
	// 调用user的getInfo方法
	fmt.Println(m.User.getInfo()) // Tom__1

}
